mod mash_data;
mod float;
mod navmesh;
pub(crate) mod agent_navigation;
pub use navmesh::NavMesh;
pub use mash_data::F64Point;
pub use agent_navigation::AgentNavigationWorld;
mod rtree;
pub use rtree::RTree;

#[cfg(test)]
mod test_navmesh {
    use crate::agent_navigation;
    use crate::agent_navigation::types::Obstacle;

    use super::navmesh::NavMesh;
    use super::F64Point;
    use std::fs::File;
    use std::io::Read;

    #[test]
    fn test_navmesh() {
        let mut file = File::open("map0101_data.json").unwrap();
        let mut str = String::new();
        file.read_to_string(&mut str).unwrap();
        let value = serde_json::from_str::<serde_json::Value>(&str).unwrap();
        let navmesh_data = value.get("navmesh").unwrap();
        let navmesh = NavMesh::from_json(&navmesh_data.to_string()).unwrap();
        // let start = F64Point::new(28051.0, 9000.0);
        // let goal = F64Point::new(28100.0, 9100.0);
        let start = F64Point::new(28193.0, 8100.0);
        let goal = F64Point::new(37857.0, 23600.0);
        let path = navmesh.search_path_smooth(&start, &goal);
        println!("{:?}", path);
        println!("{:?}", path.unwrap().len());
    }

    #[test]
    fn test_agent_world(){
        let mut file = File::open("map0103_data.json").unwrap();
        let mut str = String::new();
        file.read_to_string(&mut str).unwrap();
        let mut world = agent_navigation::AgentNavigationWorld::with_js_string(&str, true);
        world.insert_obstacle(Obstacle {
            polygon: vec![
                F64Point::new(25444.5, 22304.75),
                F64Point::new(27418.5, 21317.75),
                F64Point::new(24522.5, 19869.75),
                F64Point::new(22548.5, 20856.75),
            ],
            check_direction: true,
        });
        
        world.insert_obstacle(Obstacle {
            polygon: vec![
                F64Point::new(23079.0, 24572.0),
                F64Point::new(26128.0, 23047.5),
                F64Point::new(23334.5, 21650.75),
                F64Point::new(20285.5, 23175.25),
            ],
            check_direction: true,
        });
        
        world.insert_obstacle(Obstacle {
            polygon: vec![
                F64Point::new(26172.0, 26433.0),
                F64Point::new(29642.5, 24697.75),
                F64Point::new(26640.5, 23196.75),
                F64Point::new(23170.0, 24932.0),
            ],
            check_direction: true,
        });
        
        world.insert_obstacle(Obstacle {
            polygon: vec![
                F64Point::new(30757.0, 23523.0),
                F64Point::new(34909.5, 21446.75),
                F64Point::new(31184.0, 19584.0),
                F64Point::new(27031.5, 21660.25),
            ],
            check_direction: true,
        });
        
        world.insert_obstacle(Obstacle {
            polygon: vec![
                F64Point::new(33276.5, 25618.25),
                F64Point::new(37262.0, 23625.5),
                F64Point::new(34365.0, 22177.0),
                F64Point::new(30379.5, 24169.75),
            ],
            check_direction: true,
        });
        
        world.insert_obstacle(Obstacle {
            polygon: vec![
                F64Point::new(30595.5, 27801.75),
                F64Point::new(33725.5, 26236.75),
                F64Point::new(30756.0, 24752.0),
                F64Point::new(27626.0, 26317.0),
            ],
            check_direction: true,
        });
        
        world.insert_obstacle(Obstacle {
            polygon: vec![
                F64Point::new(35834.0, 21162.0),
                F64Point::new(39882.0, 19138.0),
                F64Point::new(36157.0, 17275.5),
                F64Point::new(32109.0, 19299.5),
            ],
            check_direction: true,
        });
        
        world.insert_obstacle(Obstacle {
            polygon: vec![
                F64Point::new(37454.5, 23127.75),
                F64Point::new(40502.0, 21604.0),
                F64Point::new(38051.0, 20378.5),
                F64Point::new(35003.5, 21902.25),
            ],
            check_direction: true,
        });
        
        world.insert_obstacle(Obstacle {
            polygon: vec![
                F64Point::new(38207.5, 25513.25),
                F64Point::new(42404.0, 23415.0),
                F64Point::new(40000.0, 22213.0),
                F64Point::new(35803.5, 24311.25),
            ],
            check_direction: true,
        });
        
        world.insert_obstacle(Obstacle {
            polygon: vec![
                F64Point::new(36008.0, 28389.0),
                F64Point::new(39476.0, 26655.0),
                F64Point::new(35872.0, 24853.0),
                F64Point::new(32404.0, 26587.0),
            ],
            check_direction: true,
        });
        
        world.insert_obstacle(Obstacle {
            polygon: vec![
                F64Point::new(32432.69921875, 18359.849609375),
                F64Point::new(32332.0234375, 18136.28515625),
                F64Point::new(33684.6015625, 17395.55078125),
                F64Point::new(33904.6640625, 17589.8515625),
            ],
            check_direction: true,
        });
        
        world.insert_obstacle(Obstacle {
            polygon: vec![
                F64Point::new(32642.0, 18439.19921875),
                F64Point::new(32541.32421875, 18215.634765625),
                F64Point::new(33893.8984375, 17474.8984375),
                F64Point::new(34113.9609375, 17669.20703125),
            ],
            check_direction: true,
        });
        
        world.insert_obstacle(Obstacle {
            polygon: vec![
                F64Point::new(32843.69921875, 18530.650390625),
                F64Point::new(32743.0234375, 18307.0859375),
                F64Point::new(34095.6015625, 17566.3515625),
                F64Point::new(34315.65625, 17760.65625),
            ],
            check_direction: true,
        });
        
        world.insert_obstacle(Obstacle {
            polygon: vec![
                F64Point::new(15556.0, 25622.0),
                F64Point::new(18482.5, 24158.75),
                F64Point::new(15549.0, 22692.0),
                F64Point::new(12622.5, 24155.25),
            ],
            check_direction: false,
        });

        let result = world.native_is_point_in_obstacle(&F64Point::new(16142.894240082413, 24310.558282317365));

        println!("{:?}", result);
    }
}
